#pragma once
#include"Epoller.hpp"
#include<memory>
#include"Com.hpp"
#include"Log.hpp"
#include"connection.hpp"
#include<map>
#include"Dispatch.hpp"
class Dispatch;
using namespace LogMoudle;
#define MAX_EVENTS 1024
class EventLoop {
    public:
        EventLoop():isrunning(false),
                    epoller(std::make_shared<Epoller>())
                    ,dispatch(std::make_unique<Dispatch>())
                    ,val(true)
        {
            dispatch->setLoop(this);
        }
        void OnceLoop(){
           int n= epoller->WaitEvent(events, MAX_EVENTS, -1);
            if(n>0){
                for(int i=0;i<n;++i){
                    //处理事件
                    if(val)
                    dispatch->listendispatch(events[i]);
                    else
                    dispatch->workerdispatch(events[i]);
                }
            }else if(n==0){
                //超时处理
                LOG(LogLevel::INFO) << "timeout";
            }else{
                //错误处理
                LOG(LogLevel::ERROR) << "epoll error";
                exit(error);
            }

        }
        void Loop(){
            while(isrunning){
                OnceLoop();
            }
        }
        void setrunning(bool run){
            this->isrunning = run;
        }
        void addconnection(std::shared_ptr<connection> conn){
            int fd = conn->getfd();
            if(isExsit(fd)){
                //存在
                LOG(LogLevel::ERROR) << "fd already exist";
                exit(error);
            }else{
                //不存在
                connections[fd]=conn;
                epoller->AddEvent(fd,EPOLLIN|EPOLLET);
            }
        }
        bool isExsit(int fd){
            auto it = connections.find(fd);
            if(it!=connections.end()){
                return true;
            }else{
                return false;
           }
        }
        std::map<int,std::shared_ptr<connection>>connections;
    private:
        bool isrunning; 
        std::shared_ptr<Epoller> epoller;
        struct epoll_event events[MAX_EVENTS];
        std::unique_ptr<Dispatch> dispatch;
        bool val;
};